#pragma once

#include "vfw.h"
#include "stdafx.h"
#include "AutoPtr.h"
#include "AutoArrayPtr.h"
#include "FrameRate.h"

namespace ManagedVC1
{
    ref class AviFileReader
    {
    public:
        AviFileReader();
        ~AviFileReader()
        {
            delete m_frameRate;
			if (m_videoStream != nullptr) { AVIStreamRelease(m_videoStream); m_videoStream = nullptr; }
			if (m_audioStream != nullptr) { AVIStreamRelease(m_audioStream); m_audioStream = nullptr; }
			if (m_aviFileIn != nullptr) { AVIFileRelease(m_aviFileIn); m_aviFileIn = nullptr; }

            AVIFileExit();
        }

        void Initialize(System::String^ fileName, CommonFrameRate^ frameRate);
        __int64 ReadVideoFrame(AutoArrayPtr<BYTE>% pVideo);
        __int64 ReadAudioFrame(BYTE** pAudio, long* audioLen);
        void SeekToBeginning();

        property unsigned long FrameCount { unsigned long get() { return m_numFrames; } }
        property unsigned long FirstVideoFrame { unsigned long get() { return m_firstVideoFrame; } }
        property unsigned long FirstAudioFrame { unsigned long get() { return m_firstAudioFrame; } }
        property System::Drawing::Size^ VideoSize { System::Drawing::Size^ get() { return gcnew System::Drawing::Size(m_videoInfoHeader->biWidth, m_videoInfoHeader->biHeight); } }
        property WAVEFORMATEX* AudioInfoHeader { WAVEFORMATEX* get() { return m_audioInfoHeader; } }

    private:
        IAVIFile* m_aviFileIn;
        AutoPtr<AVIFILEINFO> m_aviFileInInfo;
        
        IAVIStream* m_videoStream;
        AutoPtr<AVISTREAMINFO> m_videoStreamInfo;
        AutoPtr<BITMAPINFOHEADER> m_videoInfoHeader;
        
        IAVIStream* m_audioStream;
        AutoPtr<AVISTREAMINFO> m_audioStreamInfo;
        AutoPtr<WAVEFORMATEX> m_audioInfoHeader;

        AutoArrayPtr<BYTE> m_audioBuffer;
        AutoArrayPtr<BYTE> m_videoBuffer;

        CommonFrameRate^ m_frameRate;

        bool m_SwapUV;
        unsigned long m_numFrames;
        long m_YSample, m_UVSample, m_audioSamplesPos, m_firstVideoFrame, m_firstAudioFrame, m_lastAudioFrame, m_currentFrameNumber;
        int m_audioSamplesPerFrame, m_audioBufferSize;

        __int64 GetVideoTimestamp(int frameNumber);
        __int64 GetAudioTimestamp();
    };
}